package com.zlh.hdfsfilesys.controller;

import org.apache.http.HttpHost;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.BufferedReader;
import java.io.IOException;

@Controller
public class esSearchController {
    /**
     * 连接到es
     * @return
     */
    public static RestHighLevelClient  createEsClient() throws IOException {
        HttpHost host=new HttpHost("192.168.137.137",9200,"http");
        RestClientBuilder restClientBuilder= RestClient.builder(host);
        RestHighLevelClient esClient=new RestHighLevelClient(restClientBuilder);
        return esClient;
    }

    /**
     * 将读取的文件内容索引到es
     * @param esClient
     * @param indexName
     * @param in
     * @param title
     * @throws IOException
     */
    public static void index(RestHighLevelClient esClient, String indexName, BufferedReader in, String title) throws IOException {
        IndexRequest indexRequest=new IndexRequest(indexName);
        JSONArray objects=ReadFile.readFile(in,title);
        for (Object obj:objects){
            String source=obj.toString();
            indexRequest.source(source, XContentType.JSON);
            IndexResponse index=esClient.index(indexRequest, RequestOptions.DEFAULT);
        }
    }

    /**
     * 模糊查询
     * @param esClient
     * @param indexName
     * @param str
     * @return
     * @throws IOException
     */
    public static String search(RestHighLevelClient esClient,String indexName,String str) throws IOException {
        /**
         * 建立模糊搜索请求
         */
        SearchRequest searchRequest=new SearchRequest(indexName);
        SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();
        MatchQueryBuilder query=QueryBuilders.matchQuery("context",str);

        /**
         * 设置搜索结果高亮显示
         */
        HighlightBuilder highlightBuilder=new HighlightBuilder().fragmentSize(100).numOfFragments(5).noMatchSize(20);
        highlightBuilder.preTags("<strong>");
        highlightBuilder.postTags("</strong>");
        highlightBuilder.field("context");
        sourceBuilder.highlighter(highlightBuilder);

        sourceBuilder.query(query);
        searchRequest.source(sourceBuilder);
        SearchResponse search=esClient.search(searchRequest,RequestOptions.DEFAULT);
        SearchHits hits=search.getHits();
        JSONArray objects=new JSONArray();

        /**
         * 解析搜索结果
         */
        for (SearchHit hit:hits){
            JSONObject object=new JSONObject();
            object.put("took",search.getTook());
            object.put("id",hit.getId());
            object.put("totalhits",hits.getTotalHits().value);
            object.put("score",hit.getScore());
            object.put("title",hit.getSourceAsMap().get("title"));
            Text[] texts=hit.getHighlightFields().get("context").getFragments();
            for (Text t:texts){
                object.put("context",t.toString());
            }

            objects.put(object);
        }
        return objects.toString();
    }

    /**
     * 搜索接口
     * @param str
     * @param model
     * @return
     * @throws IOException
     */
    @RequestMapping("/search")
    public String searchFile(String str, Model model) throws IOException {
        model.addAttribute("searchKey",str);
        return "searchResult";
    }

    /**
     * 显示搜索结果接口
     * @param str
     * @return
     * @throws IOException
     */
    @RequestMapping("/display")
    @ResponseBody
    public String display(String str) throws IOException {
        RestHighLevelClient esClient=createEsClient();
        String  response=search(esClient,"test",str);
        esClient.close();
        return response;
    }
}
